package com.kezesong.leasing.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kezesong.leasing.common.AesUtil;
import com.kezesong.leasing.common.ResponseResult;
import com.kezesong.leasing.common.enums.OrderTradeStatusEnum;
import com.kezesong.leasing.common.enums.ReturnCodeEnum;
import com.kezesong.leasing.common.exception.CommonException;
import com.kezesong.leasing.controller.request.AddOrderReqBody;
import com.kezesong.leasing.dto.SessionInfo;
import com.kezesong.leasing.entity.OrderEntity;
import com.kezesong.leasing.service.OrderService;
import com.kezesong.leasing.service.SessionService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.ExecutionException;

@RestController
@RequestMapping("/page")
public class OrderController extends BaseController{

    @Autowired
    private OrderService orderService;

    @Autowired
    private SessionService sessionService;

    @Value("weixinPayAesKey")
    private String weixinPayAesKey;

    @PostMapping("/addOrder")
    @ApiOperation(value = "addOrder", notes = "用户提交订单后获取订单号")
    public ResponseResult<String> addOrder(@RequestBody AddOrderReqBody reqBody, HttpServletRequest httpServletRequest) throws ExecutionException, CommonException {
        try {
            OrderEntity orderEntity = new OrderEntity();
            BeanUtils.copyProperties(reqBody,orderEntity);
            orderEntity.setBuyerId(this.getBuyerId(httpServletRequest));

            String orderNO = orderService.addOrder(orderEntity);
            if (StringUtils.isBlank(orderNO)) {
                return buildNoDataResponse();
            }else {
                ResponseResult<String> responseResult = buildSucessResponse(orderNO);
                return responseResult;
            }

        } catch (CommonException commonException) {
            logger.error("OrderController.addOrder", commonException);
            return buildFailedResponse(commonException);
        }
    }

    @GetMapping("/getPrepayNo/{orderNO}")
    @ApiOperation(value = "getPrepayNo", notes = "用户选择支付获取微信支付预付单")
    public ResponseResult<String> getPrepayNo( @PathVariable String orderNo, HttpServletRequest httpServletRequest) throws ExecutionException, CommonException {
        String prepayNo = orderService.getPrepayNumber(orderNo,this.getOpenId(httpServletRequest));
        ResponseResult<String> responseResult = buildSucessResponse(prepayNo);
        if (StringUtils.isBlank(prepayNo)){
            responseResult = buildFailedResponse();
        }
        return responseResult;
    }


    /**
     *
     * 微信支付成功会推送该消息到这个接口
     * {
     *     "id": "EV-2018022511223320873",
     *     "create_time": "2015-05-20T13:29:35+08:00",
     *     "resource_type": "encrypt-resource",
     *     "event_type": "TRANSACTION.SUCCESS",
     *     "summary": "支付成功",
     *     "resource": {
     *         "original_type": "transaction",
     *         "algorithm": "AEAD_AES_256_GCM",
     *         "ciphertext": "",
     *         "associated_data": "",
     *         "nonce": ""
     *     }
     * }
     *
     * 商户解密resource得到如下报文
     * https://pay.wechatpay.cn/docs/partner/products/notification/decryption.html
     *
     * {
     *     "transaction_id":"1217752501201407033233368018",
     *     "amount":{
     *         "payer_total":100,
     *         "total":100,
     *         "currency":"CNY",
     *         "payer_currency":"CNY"
     *     },
     *     "mchid":"1230000109",
     *     "trade_state":"SUCCESS",
     *     "bank_type":"CMC",
     *     "promotion_detail":[
     *         {
     *             "amount":100,
     *             "wechatpay_contribute":0,
     *             "coupon_id":"109519",
     *             "scope":"GLOBAL",
     *             "merchant_contribute":0,
     *             "name":"单品惠-6",
     *             "other_contribute":0,
     *             "currency":"CNY",
     *             "stock_id":"931386",
     *             "goods_detail":[
     *                 {
     *                     "goods_remark":"商品备注信息",
     *                     "quantity":1,
     *                     "discount_amount":1,
     *                     "goods_id":"M1006",
     *                     "unit_price":100
     *                 },
     *                 {
     *                     "goods_remark":"商品备注信息",
     *                     "quantity":1,
     *                     "discount_amount":1,
     *                     "goods_id":"M1006",
     *                     "unit_price":100
     *                 }
     *             ]
     *         },
     *         {
     *             "amount":100,
     *             "wechatpay_contribute":0,
     *             "coupon_id":"109519",
     *             "scope":"GLOBAL",
     *             "merchant_contribute":0,
     *             "name":"单品惠-6",
     *             "other_contribute":0,
     *             "currency":"CNY",
     *             "stock_id":"931386",
     *             "goods_detail":[
     *                 {
     *                     "goods_remark":"商品备注信息",
     *                     "quantity":1,
     *                     "discount_amount":1,
     *                     "goods_id":"M1006",
     *                     "unit_price":100
     *                 },
     *                 {
     *                     "goods_remark":"商品备注信息",
     *                     "quantity":1,
     *                     "discount_amount":1,
     *                     "goods_id":"M1006",
     *                     "unit_price":100
     *                 }
     *             ]
     *         }
     *     ],
     *     "success_time":"2018-06-08T10:34:56+08:00",
     *     "payer":{
     *         "openid":"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"
     *     },
     *     "out_trade_no":"1217752501201407033233368018",
     *     "appid":"wxd678efh567hg6787",
     *     "trade_state_desc":"支付成功",
     *     "trade_type":"MICROPAY",
     *     "attach":"自定义数据",
     *     "scene_info":{
     *         "device_id":"013467007045764"
     *     }
     * }
     *
     *
     *
     *
     * 接收成功：HTTP应答状态码需返回200或204，无需返回应答报文。
     *
     * 接收失败：HTTP应答状态码需返回5XX或4XX，同时需返回应答报文，格式如下：
     *
     *
     * 参数名	变量	类型[长度限制]	必填	描述
     * 返回状态码	code	string[1,32]	是	详见下面返回状态码说明
     * 示例值：SUCCESS
     * 返回信息	message	string[1,256]	否	返回信息，为错误原因
     * 示例值：系统错误
     *
     * @param httpServletRequest
     * @return
     * @throws IOException
     */
    @PostMapping("/payNotify")
    @ApiOperation(value = "payNotify", notes = "微信支付成功后通知商户")
    public ResponseResult<String> payNotify(HttpServletRequest httpServletRequest, HttpServletResponse response) throws  IOException {
        BufferedReader streamBufferReader = new BufferedReader(
                new InputStreamReader(httpServletRequest.getInputStream(),"utf-8"));
       String jsonStr = null;
       StringBuilder stringBuilder = new StringBuilder();
       while ((jsonStr = streamBufferReader.readLine()) != null){
           stringBuilder.append(jsonStr);
        }
        System.out.println("");
        logger.info("OrderController.payNotify request params,jsonStr:{}", jsonStr);
        JSONObject jsonObject = JSON.parseObject(jsonStr);
       if ("支付成功".equals(jsonObject.getString("summary"))){
           JSONObject resource = jsonObject.getJSONObject("resource");
           String original_type = resource.getString("original_type");
           String algorithm = resource.getString("algorithm");
           String ciphertext = resource.getString("ciphertext");
           String associated_data = resource.getString("associated_data");
           String nonce = resource.getString("ciphertext");

           AesUtil aesUtil = new AesUtil(weixinPayAesKey.getBytes());
           try {
               String decryptJsonString = aesUtil.decryptToString(associated_data.getBytes(), nonce.getBytes(), ciphertext);
               logger.info("OrderController.payNotify decryptJsonString,decryptJsonString:{}", decryptJsonString);
               JSONObject decryptJsonOject = JSON.parseObject(decryptJsonString);
               String  tradeStatus = decryptJsonOject.getString("trade_state");
               if ("SUCCESS".equals(tradeStatus)){
                   String mchid = decryptJsonOject.getString("mchid");
                   String outTradeNo = decryptJsonOject.getString("out_trade_no");
                   JSONObject payer = decryptJsonOject.getJSONObject("payer");;
                   String openid = payer.getString("openid");
                   OrderEntity orderInfo = orderService.getOrder(outTradeNo);
                   int modifyResult = orderService.modifyOrderTraceStatus(orderInfo.getOrderId(), OrderTradeStatusEnum.HAS_PAY.getCode());
                   if (modifyResult>0){
                       response.setStatus(200);
                       return buildSucessResponse(null);
                   }else {
                       response.setStatus(501);
                       return buildFailedResponse();
                   }
               }

           } catch (Exception e) {
               response.setStatus(501);
               logger.error("OrderController.payNotify error", e);
           }


       }
        return null;

    }





    private int getBuyerId(HttpServletRequest httpServletRequest) throws ExecutionException, CommonException {
        SessionInfo sessionInfo = this.getSessionInfo(httpServletRequest);
        return sessionInfo.getUserId();
    }

    private String getOpenId(HttpServletRequest httpServletRequest) throws ExecutionException, CommonException {
        SessionInfo sessionInfo = this.getSessionInfo(httpServletRequest);
        return sessionInfo.getOpenId();
    }



    private SessionInfo getSessionInfo(HttpServletRequest httpServletRequest) throws ExecutionException, CommonException {
        String weixinSessionTicket = sessionService.getWeixinSessionTicket(httpServletRequest);
        SessionInfo sessionInfo = sessionService.getSessionInfo(weixinSessionTicket);
        return sessionInfo;
    }
}
